package com.xiaoxx.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xiaoxx.common.error.ErrorException;
import com.xiaoxx.common.result.RType;
import com.xiaoxx.enums.LoginEnum;
import com.xiaoxx.mapper.SysMenuMapper;
import com.xiaoxx.model.dto.sys.SysMenuDto;
import com.xiaoxx.model.entity.sys.SysMenu;
import com.xiaoxx.model.entity.sys.SysRoleMenu;
import com.xiaoxx.model.entity.sys.SysUser;
import com.xiaoxx.model.vo.sys.SysMenuVo;
import com.xiaoxx.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoxx.service.SysRoleMenuService;
import com.xiaoxx.utils.BeanDtoVoUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * base--sys--菜单管理 服务实现类
 * </p>
 *
 * @author HX
 * @since 2023-07-27
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Resource
    private SysRoleMenuService sysRoleMenuService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addSysMenu(SysMenuDto sysMenuDto) {
        SysMenu sysMenu = sysMenuDto.convert(SysMenu.class);
        boolean save = save(sysMenu);
        if (save) {
            //为超级管理员新增菜单权限
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setMenuId(sysMenu.getId());
            sysRoleMenu.setRoleId("1");
            sysRoleMenuService.save(sysRoleMenu);
        }
        return save;
    }

    @Override
    public List<SysMenuVo> findTree(SysUser sysUser) {
        List<SysMenuVo> vos = new ArrayList<>();
        //获取用户菜单
        if (LoginEnum.SUPER_ADMIN.getUserName().equals(sysUser.getUsername()) && LoginEnum.SUPER_ADMIN.getFullName().equals(sysUser.getFullName())) {
            //超级管理员看所以菜单
            vos = getMenuTree(sysUser.getId(), LoginEnum.SUPER_ADMIN.getUserName());
        } else {
            //普通管理员
            vos = getMenuTree(sysUser.getId(), LoginEnum.COMMON_ADMIN.getUserName());
        }
        return vos;
    }

    @Override
    public Boolean updMenu(SysMenuDto dto) {
        return updateById(dto.convert(SysMenu.class));
    }

    @Override
    public SysMenuVo findMenuById(String id) {
        return getById(id).convert(SysMenuVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delMenuById(String id) {
        boolean b = removeById(id);
        if (b) {
            sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>()
                    .eq(SysRoleMenu::getMenuId, id));
        }
        return b;
    }

    @Override
    public List<SysMenu> findByRoleId(String roleId) {
        List<SysMenu> list = baseMapper.findByRoleId(roleId);
        return list;
    }

    @Override
    public List<SysMenuVo> traverseMenu(List<SysMenuVo> listVo) {
        //递归遍历
        List<SysMenuVo> parentMenu = listVo.stream().filter(i -> "0".equals(i.getPid())).sorted(Comparator.comparing(SysMenuVo::getSort)).collect(Collectors.toList());

        parentMenu.forEach(i -> {
            traverseMenu(i, listVo);
        });
        return parentMenu;
    }

    @Override
    public Boolean updDisable(String id, Integer disable) {
        return update(new LambdaUpdateWrapper<SysMenu>()
                .set(SysMenu::getDisable, disable)
                .eq(SysMenu::getId, id));
    }


    private List<SysMenuVo> getMenuTree(String userId, String userName) {
        List<SysMenu> menus = new ArrayList<>();
        if (LoginEnum.SUPER_ADMIN.getUserName().equals(userName)) {
            menus = list(null);
        } else {
            menus = baseMapper.getMenuByAuth(userId);
        }
        if (menus.isEmpty()) {
            throw new ErrorException(RType.USER_NO_MENU);
        }
        List<SysMenuVo> adminMenuVos = BeanDtoVoUtil.listVo(menus, SysMenuVo.class);
        //递归遍历
        List<SysMenuVo> parentMenu = adminMenuVos.stream().filter(i -> "0".equals(i.getPid())).sorted(Comparator.comparing(SysMenuVo::getSort)).collect(Collectors.toList());

        parentMenu.forEach(i -> {
            traverseMenu(i, adminMenuVos);
        });
        return parentMenu;
    }

    private void traverseMenu(SysMenuVo i, List<SysMenuVo> adminMenuVos) {
        List<SysMenuVo> vos = new ArrayList<>();
        adminMenuVos.forEach(one -> {
            if (i.getId().equals(one.getPid())) {
                traverseMenu(one, adminMenuVos);
                vos.add(one);
            }
        });
        //排序
        List<SysMenuVo> collect = vos.stream().sorted(Comparator.comparing(SysMenuVo::getSort)).collect(Collectors.toList());
        i.setChildrens(collect);
    }
}
